#include "ioMsgHandler.h"
#include "ioSerial.h"
#include "ioUserSettings.h"
#include "ESP8266WiFi.h"
#include "ioIR.h"
#include "include/ir_ac_control.h"
#include "ioOTA.h"
#include "ioUDP.h"
#include "iomqtt.h"
#include "RCSwitch.h"
#include "iodevice.h"
#include "ioWebserver.h"
#include "HLW9032.h"
StaticJsonDocument<1024> send_msg_doc;
StaticJsonDocument<1024> recv_msg_doc;

void rsp_msg(MsgType msg_type)
{
    if (msg_type == HTTP)
    {
        char sendbuf[512] = {0};
        serializeJson(send_msg_doc, sendbuf, 512);
        webserver_resp(sendbuf);
    }
    else
    {
        returnUDP(&send_msg_doc);
    }
}


//TODO mqtt和udp发送接收消息处理统一起来
bool msgHandle(StaticJsonDocument<1024> *p_recv_msg_doc, MsgType msg_type)
{
    serializeJsonPretty(*p_recv_msg_doc, IO_DEBUG);
    IO_DEBUG.println();
    JsonObject obj = p_recv_msg_doc->as<JsonObject>();
    String ip_string = obj["params"]["ip"];
    send_msg_doc.clear();

    if (obj["cmd"] == "shareinfo") //收到客户端分享信息
    {
        obj["ip"] = remoteIP.toString();
        IPAddress ip(255, 255, 255, 255);
        sendUDP(p_recv_msg_doc, ip);
        return true;
    }
    else if (obj["cmd"] == "setsta")
    {
        if (obj["stas"] == 1)
        {
            device_out_set(0,1);
            devstas = 1;
            LOGLN("setstas1");
        }
        else
        {
            devstas = 0;
            device_out_set(0,0);
            LOGLN("setstas0");
        }
        send_msg_doc["cmd"] = "io";
        send_msg_doc["stas"] = devstas;
        rsp_msg(msg_type);
        mqttPublishnum("$dp", "stas", devstas);
    }
    else if (obj["cmd"] == "config")
    {
        JsonObject params = obj["params"];
        for (JsonPair kv : params)
        {
            ConfigData[kv.key()] = kv.value();
        }
        send_msg_doc["cmd"] = "return";
        send_msg_doc["params"]["message"] = "set success";
        settingsSave();
        rsp_msg(msg_type);
    }
    else if (obj["cmd"] == "setname")
    {
        ConfigData["name"] = obj["name"];
        settingsSave();
        String name = ConfigData["name"];
        mqttPublish("$dp", "name", name.c_str());
        rsp_msg(msg_type);
    }
    else if (obj["cmd"] == "setargb")
    {
        argb_set((uint32_t)obj["value"]);
        mqttPublishnum("$dp", "argb", (uint32_t)obj["value"]);
        rsp_msg(msg_type);
    }
    else if (obj["cmd"] == "setroom")
    {
        ConfigData["room"] = obj["room"];
        settingsSave();
        String room = ConfigData["room"];
        mqttPublish("$dp", "room", room.c_str());
    }
    else if (obj["cmd"] == "setimg")
    {
        ConfigData["img"] = obj["img"];
        settingsSave();
        String room = ConfigData["img"];
        mqttPublish("$dp", "img", room.c_str());
    }
    else if (obj["cmd"] == "clearconfig")
    {
        ConfigData.clear();
        settingsSave();
    }
    else if (obj["cmd"] == "discovery")
    {
        String chip_id = String(ESP.getChipId(), HEX);
        chip_id.toUpperCase();
        send_msg_doc["cmd"] = "upload";
        if (WiFi.status() == WL_CONNECTED)
        {
            send_msg_doc["params"]["ip"] = WiFi.localIP().toString();
        }
        else
        {
            send_msg_doc["params"]["ip"] = "192.168.4.1";
        }

        send_msg_doc["params"]["mac"] = chip_id;
        send_msg_doc["params"]["type"] = DEVTYPE;
        if (ConfigData.containsKey("mqtt"))
        {
            send_msg_doc["params"]["mqtt"]["clientId"] = ConfigData["mqtt"]["clientId"];
        }

        if (ConfigData.containsKey("send_pin"))
        {
            send_msg_doc["params"]["send_pin"] = ConfigData["send_pin"];
        }

        if (ConfigData.containsKey("receive_pin"))
        {
            send_msg_doc["params"]["receive_pin"] = ConfigData["receive_pin"];
        }
        if (ConfigData.containsKey("version"))
        {
            send_msg_doc["params"]["version"] = ConfigData["version"];
        }
        if (msg_type == HTTP)
        {
            char sendbuf[512] = {0};
            serializeJson(send_msg_doc, sendbuf, 512);

            webserver_resp(sendbuf);
        }
        else
        {
            String ip_string = obj["params"]["ip"];
            IPAddress remote_ip;
            remote_ip.fromString(ip_string);
            returnUDP(&send_msg_doc);
        }
    }
    else if (obj["cmd"] == "update")
    {
        JsonObject params = obj["params"];
        String url = params["url"];
        otaUpdate(url);
    }
    else if (obj["cmd"] == "sta_config")
    {
        if (obj.containsKey("ssid"))
        {
            if (obj.containsKey("pass"))
            {
                String ssid = obj["ssid"];
                String pass = obj["pass"];
                WiFi.begin(ssid.c_str(), pass.c_str());
            }
        }
    }
    else if (obj["cmd"] == "closeAP")
    {
        WiFi.mode(WIFI_STA); //配置为STA模式
    }
    else if (obj["cmd"] == "reload")
    {
        WiFi.disconnect(true);
        delay(3000);
        SPIFFS.format();
        ESP.reset();
    }
    else if (obj["cmd"] == "getwifilist")
    {
        ERRORLN("getwifilist");
        send_msg_doc["cmd"] = "wifilist";
        String ssid = "";
        int n = WiFi.scanNetworks();
        Serial.println("scan done");
        //TODO 将rssi信息也发送出去才好
        if (n == 0)
            Serial.println("no networks found");
        else
        {
            Serial.print(n);
            Serial.println(" networks found");
            for (int i = 0; i < n; ++i)
            {
                ssid = ssid + WiFi.SSID(i) + ',';
            }
        }
        send_msg_doc["ssid"] = ssid;
        char sendbuf[512] = {0};
        serializeJson(send_msg_doc, sendbuf, 512);
        void webserver_resp(char *data);
        webserver_resp(sendbuf);
    }  
    else if (obj["cmd"] == "broadpower")
    {
        HLW8032_data.broadpower = 1;
        rsp_msg(msg_type);
    }  
    else if (obj["cmd"] == "getpower")
    {
        ERRORLN("getwifilist");
        if (msg_type == HTTP)
        {
            send_msg_doc["cmd"] = "power";
            send_msg_doc["volt"] = HLW8032_data.volt_value;
            send_msg_doc["curr"] = HLW8032_data.curr_value;
            send_msg_doc["power"] = HLW8032_data.power_value;
            rsp_msg(msg_type);
        }
        else
        {
            HLW8032_data.pubnum = 10;
        }
    }

//--------------------------------------------------------------------------------
#if (HAS_IRF == 1)
    else if (obj["cmd"] == "send")
    {
        JsonObject params = obj["params"];
        if (params.containsKey("status"))
        {
            JsonObject statusJson = params["status"];
            t_remote_ac_status status;
            status.ac_power = t_ac_power((int)statusJson["power"]);
            status.ac_temp = t_ac_temperature((int)statusJson["temperature"]);
            status.ac_mode = t_ac_mode((int)statusJson["mode"]);
            status.ac_swing = t_ac_swing((int)statusJson["swing"]);
            status.ac_wind_speed = t_ac_wind_speed((int)statusJson["speed"]);
            status.ac_display = 1;
            status.ac_timer = 0;
            status.ac_sleep = 0;
            String file_name = params["file"];
            sendStatus(file_name, status);
        }
    }
    else if (obj["cmd"] == "enable_irres")
    {
        ir_recv->enableIRIn();
    }
    else if (obj["cmd"] == "disable_irres")
    {
        ir_recv->disableIRIn();
    }
    else if (obj["cmd"] == "sendir")
    {
        ir_recv->disableIRIn();
        pilot_set(1, 0);
        ir_send->send(obj["irtype"], obj["value"], obj["bits"]);
        pilot_set(0, 0);
    }
    else if (obj["cmd"] == "enable_rfres")
    {
        mySwitch.enableReceive(4);
    }
    else if (obj["cmd"] == "disable_rfres")
    {
        mySwitch.disableReceive();
    }
    else if (obj["cmd"] == "sendrf")
    {
        mySwitch.disableReceive();
        pilot_set(1, 0);
        mySwitch.setProtocol((uint32_t)obj["irtype"], (uint32_t)obj["width"]);
        if (obj.containsKey("Repeat"))
            mySwitch.setRepeatTransmit((uint32_t)obj["Repeat"]);
        else
            mySwitch.setRepeatTransmit(15);
        mySwitch.enableTransmit(13);
        mySwitch.send((uint64_t)obj["value"], (uint32_t)obj["bits"]);
        pilot_set(0, 0);
    }
#endif
    return true;
}